﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using AdminModule.IndexMarkServiceReference;

namespace System.Collections.ObjectModel
{
    public static class ObvervableCollectionExtensions
    {
        /// <summary>
        /// Очищает текущую коллекцию и заполняет ее элементами переданной коллекции
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="c"></param>
        /// <param name="list"></param>
        public static void LoadWithClear<T>(this ObservableCollection<T> c, IEnumerable<T> list)
        {
            c.Clear();
            foreach (T el in list)
            {
                c.Add(el);
            }
        }

        public static void LoadWithoutClear<T>(this ObservableCollection<T> c, IEnumerable<T> list)
        {
            foreach (T el in list)
            {
                c.Add(el);
            }
        }

        /// <summary>
        /// Удаляет из текущей коллекции объекты, состояние которых Unchanged и заполняет ее элементами переданной коллекции
        /// </summary>
        /// <typeparam name="E"></typeparam>
        /// <param name="c"></param>
        /// <param name="list"></param>
        public static void LoadFrom<E>(this ObservableCollection<DTOBase> c, IEnumerable<E> list)
        {
            List<DTOBase> tmp = new List<DTOBase>();
            // Ищем объекты, подлежащие удалению
            foreach (DTOBase el in c)
            {
                if (el.State == StateObject.Unchanged) tmp.Add(el);
            }
            // Удаляем объекты
            foreach (DTOBase el in tmp)
            {
                c.Remove(el);
            }
            // Заполняем объектами из переданной коллекции
            foreach (E el in list)
            {
                c.Add(el as DTOBase);
            }
        }

        /// <summary>
        /// Добавляет элементы из коллекции
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="c"></param>
        /// <param name="list"></param>
        public static void AddFrom<T>(this ObservableCollection<T> c, IEnumerable<T> list)
        {
            foreach (T el in list)
            {
                c.Add(el);
            }
        }

        /// <summary>
        /// Добавляет элемент в начало коллекции
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="collection"></param>
        public static void AddToForward<T>(this ObservableCollection<T> collection, T item)
        {
            ObservableCollection<T> tmp = new ObservableCollection<T>();
            foreach (T el in collection)
            {
                tmp.Add(el);
            }
            collection.Clear();
            collection.Add(item);
            foreach (T el in tmp)
            {
                collection.Add(el);
            }
        }

        public static void Replace<T>(this ObservableCollection<T> collection, T oldItem, T newItem)
        {
            int index = collection.IndexOf(oldItem);
            if (index < 0)
            {
                throw new Exception("Элемент oldItem отсутствует в коллекции");
            }
            collection.RemoveAt(index);
            collection.Insert(index, newItem);
        }

        public static ObservableCollection<T> MyCast<T>(this ObservableCollection<object> collection)
        {
            ObservableCollection<T> res = new ObservableCollection<T>();
            foreach(object el in collection)
            {
                res.Add((T)el);
            }
            return res;
        }

        public static void AddUnique<T>(this ObservableCollection<T> collection, T obj)
        {
            if (!collection.Contains(obj)) collection.Add(obj);
        }
    }
}
